package com.github.base.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.base.domain.Dept;
import com.github.base.domain.User;
import com.github.base.dto.dept.*;
import com.github.base.exception.CommonException;
import com.github.base.global.Const;
import com.github.base.mapper.DeptMapper;
import com.github.base.mapper.UserMapper;
import com.github.base.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 机构Service
 *
 * @author zhouwentong
 * Create by zhouwentong on 2021/01/28
 */

@Slf4j
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private UserMapper userMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveDept(DeptAddDTO deptAddDTO) {
        //判断添加机构属于当前用户机构子节点  TODO

        //查询同一父级下是否重复
        String dt = deptAddDTO.getDeptName();
        QueryWrapper<Dept> qw = new QueryWrapper<>();
        qw.lambda().eq(Dept::getDeptName, dt).eq(Dept::getParentId, deptAddDTO.getParentId()).eq(Dept::getState, Const.YES);
        Long integer = deptMapper.selectCount(qw);
        if (integer > 0) {
            throw new CommonException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "机构名称不能重复");
        }
        Dept dept = new Dept();
        dept.setParentId(deptAddDTO.getParentId());
        dept.setDeptName(deptAddDTO.getDeptName().trim());
        dept.setDeptDesc(StringUtils.isNotBlank(deptAddDTO.getDeptDesc()) ? deptAddDTO.getDeptDesc().trim() : "");
        dept.setDeptDeep(deptAddDTO.getParentDeptDeep() + 1);
        //获取同级排序最大值
        Dept dept1 = deptMapper.selectOne(new QueryWrapper<Dept>().select("parent_id,MAX(sort_number) as sort_number").eq("parent_id", deptAddDTO.getParentId()).groupBy("parent_id"));
        dept.setSortNumber(dept1 == null ? 1 : dept1.getSortNumber() + 1);
        dept.setOperable(Const.YES);
        dept.setUsable(deptAddDTO.getUsable());
        dept.setState(Const.YES);
        dept.setCreateTime(LocalDateTime.now());
        dept.setModifyTime(LocalDateTime.now());
        deptMapper.insert(dept);
    }


    @Override
    public List<Dept> current(DeptSearchDTO deptSearchDTO) {
//        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda().eq(Dept::getOperable, Const.YES)
//                .eq(Dept::getState, Const.YES)
//                .like(StringUtils.isNotBlank(deptSearchDTO.getDeptName()), Dept::getDeptName, deptSearchDTO.getDeptName())
//                .eq(deptSearchDTO.getUsable() != null, Dept::getUsable, deptSearchDTO.getUsable())
//                .orderByAsc(Dept::getSortNumber);
//        List<Dept> depts = deptMapper.selectList(queryWrapper);
        // 获取当前用户 父级parentId
        long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);
        Long deptId = user.getDeptId();
        List<Dept> deptList = findChildById(deptId);
        Dept currentDept = getById(deptId);
        deptList.add(currentDept);
        return deptList;
//
//        return TreeUtil.build(deptList, 0L, new NodeParser<Dept, Long>() {
//            @Override
//            public void parse(Dept dept, Tree<Long> tree) {
//                tree.setId(dept.getId());
//                tree.setParentId(dept.getParentId());
//                tree.setName(dept.getDeptName());
//                // 扩展属性 ...
//                tree.putExtra("deptDeep", dept.getDeptDeep());
//                tree.putExtra("deptCode", dept.getDeptCode());
//                tree.putExtra("deptDesc", dept.getDeptDesc());
//                tree.putExtra("sortNumber", dept.getSortNumber());
//                tree.putExtra("usable", dept.getUsable());
//                tree.putExtra("operable", dept.getOperable());
//            }
//        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDept(DeptUpdateDTO deptUpdateDTO) {
        //判断添加机构属于当前用户机构子节点  TODO

        String deptName = deptUpdateDTO.getDeptName().trim();
        Dept dept = deptMapper.selectById(deptUpdateDTO.getId());
        if (dept != null) {
            //名称不一致
            if (!deptName.equals(dept.getDeptName())) {
                //查询同一父级下是否重复
                QueryWrapper<Dept> queryWrapper = new QueryWrapper();
                queryWrapper.lambda().eq(Dept::getDeptName, deptName).eq(Dept::getParentId, deptUpdateDTO.getParentId()).eq(Dept::getState, Const.YES);
                Long integer = deptMapper.selectCount(queryWrapper);
                if (integer > 0) {
                    throw new CommonException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "机构名称不能重复");
                }
            }
            dept.setId(deptUpdateDTO.getId());
            dept.setDeptName(deptName);
            dept.setDeptDesc(deptUpdateDTO.getDeptDesc() == null ? "" : deptUpdateDTO.getDeptDesc().trim());
            dept.setUsable(deptUpdateDTO.getUsable());
            dept.setModifyTime(LocalDateTime.now());
            deptMapper.updateById(dept);
        } else {
            throw new CommonException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "id不存在");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteDept(DeptDeleteDTO deptDeleteDTO) {
        Dept dept = deptMapper.selectById(deptDeleteDTO.getId());
        if (dept != null) {
            //判断机构是否有用户在使用
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(User::getDeptId, dept.getId()).eq(User::getState, Const.YES);
            Long integer = userMapper.selectCount(queryWrapper);
            if (integer > 0) {
                throw new CommonException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "机构已有用户使用,不可删除");
            }
            dept.setState(Const.NO);
            deptMapper.updateById(dept);
        } else {
            throw new CommonException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "id不存在");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void OrderDept(DeptOrderDTO deptOrderDTO) {
        Dept dept1 = deptMapper.selectById(deptOrderDTO.getFId());
        Integer sortNumber1 = dept1.getSortNumber();
        Dept dept2 = deptMapper.selectById(deptOrderDTO.getSId());
        Integer sortNumber2 = dept2.getSortNumber();
        dept1.setSortNumber(sortNumber2);
        deptMapper.updateById(dept1);
        dept2.setSortNumber(sortNumber1);
        deptMapper.updateById(dept2);
    }

    /**
     * 通过id查询子机构
     *
     * @param id
     * @return
     */
    @Override
    public List<Dept> findChildById(Long id) {
        List<Dept> result = new ArrayList<>();
        findChildrenRecursively(id, result);
        return result;
    }

    private void findChildrenRecursively(Long parentId, List<Dept> result) {
        List<Dept> children = findByParentId(parentId);
        if (children != null && !children.isEmpty()) {
            result.addAll(children);
            for (Dept child : children) {
                findChildrenRecursively(child.getId(), result);
            }
        }
    }

    private List<Dept> findByParentId(Long parentId) {
        LambdaQueryWrapper<Dept> query = Wrappers.lambdaQuery(Dept.class);
        query.eq(Dept::getParentId, parentId);
        query.eq(Dept::getState, Const.YES);
        query.eq(Dept::getUsable, Const.YES);
        return deptMapper.selectList(query);
    }
}
